use std::cell::RefCell;
use std::mem::ManuallyDrop;
use std::rc::Rc;
use crate::co;
use crate::decl::*;
use crate::gui::{*, iterators::*};
use crate::kernel::privs::*;
use crate::msg::*;
use crate::prelude::*;
pub struct TreeViewItem<'a, T: 'static = ()> {
owner: &'a TreeView<T>,
hitem: HTREEITEM,
}
impl<'a, T> TreeViewItem<'a, T> {
#[must_use]
pub(in crate::gui) const fn new(
owner: &'a TreeView<T>,
hitem: HTREEITEM,
) -> Self
{
Self { owner, hitem }
}
#[must_use]
fn raw_clone(&self) -> Self {
Self {
owner: self.owner,
hitem: unsafe { self.hitem.raw_copy() },
}
}
pub fn add_child(&self,
text: &str,
icon_index: Option<u32>,
data: T,
) -> Self
{
self.owner.raw_insert_item(Some(&self.hitem), text, icon_index, data)
}
#[must_use]
pub fn data(&self) -> Option<Rc<RefCell<T>>> {
self.data_lparam()
.map(|pdata| {
let rc_data = ManuallyDrop::new(unsafe { Rc::from_raw(pdata) });
Rc::clone(&rc_data)
})
}
#[must_use]
pub(in crate::gui) fn data_lparam(&self) -> Option<*mut RefCell<T>> {
let mut tvix = TVITEMEX::default();
tvix.hItem = unsafe { self.hitem.raw_copy() };
tvix.mask = co::TVIF::PARAM;
unsafe {
self.owner.hwnd()
.SendMessage(tvm::GetItem { tvitem: &mut tvix })
}.unwrap();
match tvix.lParam {
0 => None,
lp => Some(lp as _),
}
}
pub fn delete(&self) {
unsafe {
self.owner.hwnd()
.SendMessage(tvm::DeleteItem { hitem: &self.hitem })
}.unwrap();
}
pub fn edit_label(&self) -> HWND {
unsafe {
self.owner.hwnd()
.SendMessage(tvm::EditLabel { hitem: &self.hitem })
}.unwrap()
}
pub fn ensure_visible(&self) -> bool {
unsafe {
self.owner.hwnd()
.SendMessage(tvm::EnsureVisible { hitem: &self.hitem }) != 0
}
}
pub fn expand(&self, expand: bool) {
unsafe {
self.owner.hwnd()
.SendMessage(tvm::Expand {
hitem: &self.hitem,
action: if expand { co::TVE::EXPAND } else { co::TVE::COLLAPSE },
})
}.unwrap();
}
#[must_use]
pub const fn htreeitem(&self) -> &HTREEITEM {
&self.hitem
}
#[must_use]
pub fn is_expanded(&self) -> bool {
unsafe {
self.owner.hwnd()
.SendMessage(tvm::GetItemState {
hitem: &self.hitem,
mask: co::TVIS::EXPANDED,
})
}.has(co::TVIS::EXPANDED)
}
#[must_use]
pub fn is_root(&self) -> bool {
self.parent().is_none()
}
#[must_use]
pub fn iter_children(&self,
) -> impl Iterator<Item = TreeViewItem<'a, T>> + 'a
{
TreeViewChildItemIter::new(self.owner, Some(self.raw_clone()))
}
#[must_use]
pub fn iter_next_siblings(&self,
) -> impl Iterator<Item = TreeViewItem<'a, T>> + 'a
{
TreeViewItemIter::new(self.owner, Some(self.raw_clone()), co::TVGN::NEXT)
}
#[must_use]
pub fn iter_prev_siblings(&self,
) -> impl Iterator<Item = TreeViewItem<'a, T>> + 'a
{
TreeViewItemIter::new(self.owner, Some(self.raw_clone()), co::TVGN::PREVIOUS)
}
#[must_use]
pub fn parent(&self) -> Option<Self> {
unsafe {
self.owner.hwnd()
.SendMessage(tvm::GetNextItem {
relationship: co::TVGN::PARENT,
hitem: Some(&self.hitem),
})
}.map(|hitem| TreeViewItem::new(self.owner, hitem))
}
pub fn set_text(&self, text: &str) {
let mut buf = WString::from_str(text);
let mut tvix = TVITEMEX::default();
tvix.hItem = unsafe { self.hitem.raw_copy() };
tvix.mask = co::TVIF::TEXT;
tvix.set_pszText(Some(&mut buf));
unsafe {
self.owner.hwnd()
.SendMessage(tvm::SetItem { tvitem: &tvix })
}.unwrap();
}
#[must_use]
pub fn text(&self) -> String {
let mut tvix = TVITEMEX::default();
tvix.hItem = unsafe { self.hitem.raw_copy() };
tvix.mask = co::TVIF::TEXT;
let mut buf = WString::new_alloc_buf(MAX_PATH + 1); tvix.set_pszText(Some(&mut buf));
unsafe {
self.owner.hwnd()
.SendMessage(tvm::GetItem { tvitem: &mut tvix })
}.unwrap();
buf.to_string()
}
}